home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / DEMON / RISCOS2 / TCP_131S.ARC / c / main < prev    next >
Text File  |  1994-03-07  |  22KB  |  885 lines

  1. /* Main network program - provides both client and server functions */
  2.  
  3. #define HOSTNAMELEN 32          /* changed from 16 by Bdale 860812 */
  4.  
  5. #define ESC 29
  6.  
  7. extern char config[];   /* File to read setup from */
  8. extern char startup[];  /* File to read startup commands from */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <time.h>
  14. #include <stdarg.h>
  15. #include <ctype.h>
  16. #include "config.h"
  17. #include "global.h"
  18. #include "mbuf.h"
  19. #include "netuser.h"
  20. #include "timer.h"
  21. #include "icmp.h"
  22. #include "iface.h"
  23. #include "ip.h"
  24. #include "tcp.h"
  25. #include "ax25.h"
  26. #include "netrom.h"
  27. #include "remote.h"
  28. #include "ftp.h"
  29. #include "telnet.h"
  30. #include "session.h"
  31. #include "cmdparse.h"
  32. #include "asy.h"
  33. #include "chat.h"
  34. #include "slip.h"
  35. #include "nrs.h"
  36. #include "trace.h"
  37. #include "mem.h"
  38. #include "arp.h"
  39. #include "ax_mbx.h"
  40. #include "finger.h"
  41. #include "internet.h"
  42. #include "kiss.h"
  43. #include "lapb.h"
  44. #include "nr4.h"
  45. #include "ping.h"
  46. #include "pop.h"
  47. #include "nntp.h"
  48. #include "smtp.h"
  49. #include "NetTime.h"
  50. #include "udp.h"
  51. #include "misc.h"
  52. #include "domain.h"
  53. #include "arc.h"
  54. #include "driver.h"
  55. #include "pppdriver.h"
  56.  
  57. #include "alarm.h"
  58.  
  59. extern int (*driver_load(char*))(int,...);
  60.  
  61. /* Dummy structure for loopback tracing */
  62. struct interface loopback = { 
  63.   NULLIF, "loopback" };
  64.  
  65. extern struct interface *ifaces;
  66. extern char version[];
  67. extern struct mbuf *loopq;
  68.  
  69. extern Terminal *MWin;
  70.  
  71. int mode;
  72. char badhost[] = "Unknown host %s\r\n";
  73. char hostname[HOSTNAMELEN];     
  74. unsigned nsessions = NSESSIONS;
  75. int16 lport    = 1001;
  76. char *prompt   = "net> ";
  77. char nospace[] = "No space!!\r\n";        /* Generic malloc fail message */
  78. int attended = 1;
  79. int ttyflow = 1;                        /* tty flow control */
  80. static char *ttybuf;
  81.  
  82. extern int doresolve(int, char **);
  83.  
  84. static int doexit(int, char **);
  85. static int doattach(int, char **);
  86. static int doecho(int, char **);
  87. static int doeol(int, char **);
  88. static int dohostname(int, char **);
  89. static int dolog(int, char **);
  90. static int dohelp(int, char **);
  91. static int domode(int, char **);
  92. static int doparam(int, char **);
  93. static int doremote(int, char **);
  94. static int dostart(int, char **);
  95. static int dostop(int, char **);
  96. static int dotrace(int, char **);
  97. static int dosource(int, char **);
  98. static int dounattend(int, char **);
  99.  
  100. static void showtrace(struct interface *);
  101. static int  asy_attach(int, char **);
  102.  
  103. struct cmds cmds[] = {
  104.   /* The "go" command must be first */
  105.   "",             go,             0, NULLCHAR,    NULLCHAR,
  106.   "arp",          doarp,          0, NULLCHAR,    NULLCHAR,
  107.   "asystat",      doasystat,      0, NULLCHAR,    NULLCHAR,
  108.   "ax25",         doax25,         0, NULLCHAR,    NULLCHAR,
  109.   "attach",       doattach,       2, "attach <hardware> <hw specific options>", NULLCHAR,
  110.   /* This one is out of alpabetical order to allow abbreviation to "c" */
  111.   "connect",      doconnect,      3,"connect <interface> <callsign> [digipeaters]",
  112.   NULLCHAR,
  113.   "chat",         dochat,         0, "chat <interface> <error-send> [expect-send pairs]",    NULLCHAR,
  114.   "chattrace",    chat_trace,     0, NULLCHAR,    NULLCHAR,
  115.   "close",        doclose,        0, NULLCHAR,    NULLCHAR,
  116.   "disconnect",   doclose,        0, NULLCHAR,    NULLCHAR,
  117.   "domain",       dodomain,       0, NULLCHAR,    NULLCHAR,
  118.   "echo",         doecho,         0, NULLCHAR,    "echo [refuse|accept]",
  119.   "eol",          doeol,          0, NULLCHAR,    "eol options: unix, standard",
  120.   "exit",         doexit,         0, NULLCHAR,    NULLCHAR,
  121.   "finger",       dofinger,       0, NULLCHAR,    NULLCHAR,
  122.   "forward",      doforward,      0, NULLCHAR,    NULLCHAR,
  123.   "ftp",          doftp,          2, "ftp <address>",     NULLCHAR,
  124.   "help",         dohelp,         0, NULLCHAR,    NULLCHAR,
  125.   "hop",          dohop,          2, NULLCHAR,    NULLCHAR, 
  126.   "hostname",     dohostname,     0, NULLCHAR,    NULLCHAR,
  127.   "kick",         dokick,         0, NULLCHAR,    NULLCHAR,
  128.   "log",          dolog,          0, NULLCHAR,    NULLCHAR,
  129.   "ip",           doip,           0, NULLCHAR,    NULLCHAR,
  130.   "mbox",         dombox,         0, NULLCHAR,    NULLCHAR,
  131.   "mem",          domem,          0, NULLCHAR,    NULLCHAR,   
  132.   "mode",         domode,         2, "mode <interface>",  NULLCHAR,
  133.   "netrom",       donetrom,       0, NULLCHAR,    NULLCHAR,
  134.   "nntp",         donntp,         0, NULLCHAR,    NULLCHAR,
  135.   "nrstat",       donrstat,       0, NULLCHAR,    NULLCHAR,
  136.   "param",        doparam,        2, "param <interface>", NULLCHAR,
  137.   "ping",         doping,         0, NULLCHAR,    NULLCHAR,
  138.   "pop",          dopop,          0, NULLCHAR,    NULLCHAR,
  139.   "quit",         doexit,         0, NULLCHAR,    NULLCHAR,
  140.   "record",       dorecord,       0, NULLCHAR,    NULLCHAR,            
  141.   "remote",       doremote,       4, "remote <address> <port> <command>", NULLCHAR,
  142.   "reset",        doreset,        0, NULLCHAR,    NULLCHAR,
  143.   "resolve",      doresolve,      0, NULLCHAR,    NULLCHAR,
  144.   "route",        doroute,        0, NULLCHAR,    NULLCHAR,
  145.   "session",      dosession,      0, NULLCHAR,    NULLCHAR,
  146.   "smtp",         dosmtp,         0, NULLCHAR,    NULLCHAR,
  147.   "source",       dosource,       2, "source <filename>", NULLCHAR,
  148.   "start",        dostart,        2, "start <servername>",NULLCHAR,
  149.   "stop",         dostop,         2, "stop <servername>", NULLCHAR,
  150.   "tcp",          dotcp,          0, NULLCHAR,    NULLCHAR,
  151.   "telnet",       dotelnet,       2, "telnet <address>",  NULLCHAR,
  152.   "time",         dotime,         1, NULLCHAR,  NULLCHAR,
  153.   "trace",        dotrace,        0, NULLCHAR,    NULLCHAR,
  154.   "udp",          doudp,          0, NULLCHAR,    NULLCHAR,
  155.   "unattended",   dounattend,     0, NULLCHAR,    NULLCHAR,
  156.   "upload",       doupload,       0, NULLCHAR,    NULLCHAR,
  157.   "window",       dowin,          0, NULLCHAR,    NULLCHAR, 
  158.   "?",            dohelp,         0, NULLCHAR,    NULLCHAR,
  159.   NULLCHAR,       NULLFP,         0,
  160.   "Unknown command; type \"?\" for list",   NULLCHAR, 
  161. };
  162.  
  163. /* "start" and "stop" subcommands */
  164.  
  165. static struct cmds startcmds[] = {
  166.   "discard",      dis1,           0, NULLCHAR, NULLCHAR,
  167.   "echo",         echo1,          0, NULLCHAR, NULLCHAR,
  168.   "finger",       finger1,        0, NULLCHAR, NULLCHAR,
  169.   "ftp",          ftp1,           0, NULLCHAR, NULLCHAR,
  170.   "smtp",         smtp1,          0, NULLCHAR, NULLCHAR,
  171.   "telnet",       tn1,            0, NULLCHAR, NULLCHAR,
  172.   NULLCHAR,       NULLFP,         0,
  173.   "start options: discard, echo, finger, ftp, smtp, telnet", NULLCHAR,
  174. };
  175.  
  176. static struct cmds stopcmds[] = {
  177.   "discard",      dis0,           0, NULLCHAR, NULLCHAR,
  178.   "echo",         echo0,          0, NULLCHAR, NULLCHAR,
  179.   "finger",       finger0,        0, NULLCHAR, NULLCHAR,
  180.   "ftp",          ftp0,           0, NULLCHAR, NULLCHAR,
  181.   "smtp",         smtp0,          0, NULLCHAR, NULLCHAR,
  182.   "telnet",       tn0,            0, NULLCHAR, NULLCHAR,
  183.   NULLCHAR,       NULLFP,         0,
  184.   "stop options: discard, echo, finger, ftp, smtp, telnet", NULLCHAR,
  185. };
  186.  
  187. static void AutoExec(int at, void *handle)
  188. {
  189.   char *args[2];
  190.  
  191.   /* read default start_up file */
  192.   args[1] = startup;
  193.   dosource(2, args);
  194. }
  195.  
  196. void net_init(void)
  197. {
  198.   char *args[2];
  199.  
  200.   sessions = (struct session *) calloc(nsessions, sizeof(struct session));
  201.   memset(udps, NUDP * sizeof(struct udp_cb *), '\0');
  202.   ttydriv('\n',&ttybuf); /* Initialise the keyboard buffer */
  203.  
  204.   Read_Domain_File();
  205.  
  206.   /* read default start_up file */
  207.   args[1] = config;
  208.   dosource(2, args);
  209.  
  210.   cmdmode();
  211.   alarm_set(alarm_timenow() + 100, AutoExec, 0);
  212. }
  213.  
  214. void net_keyboard(int c)
  215. {
  216.   int16 cnt;
  217.  
  218.   /* c == 0x1CA means the command escape key (F10) */
  219.   if(c == 0x1CA || c == ESC)
  220.   {
  221.     if(mode != CMD_MODE)
  222.     {
  223.       cwprintf(NULL, "\r\n");
  224.       cmdmode();
  225.     }
  226.     return;
  227.   }
  228.   if ((cnt = ttydriv(c,&ttybuf)) == 0)
  229.   {
  230.     ttyflow = 0;    /* stop output to screen */
  231.     return;
  232.   }
  233.   else
  234.       {
  235.     ttyflow = 1;    /* restart output again */
  236.     if(mode != CMD_MODE)
  237.       go(NULL);   /* display pending chars */
  238.   }
  239.  
  240.   switch(mode)
  241.   {
  242.   case CMD_MODE:
  243.     cmdparse(cmds, ttybuf, NULL);
  244.     break;
  245.   case CONV_MODE:
  246.     if(current->parse != NULLVFP)
  247.       (*current->parse)(NULL, ttybuf, cnt);
  248.     break;
  249.   }
  250.   if(mode == CMD_MODE)
  251.     cwprintf(NULL, prompt);
  252. }
  253.  
  254. void net_poll(void)
  255. {
  256.   struct interface *ifp;
  257.   struct mbuf *bp;
  258.   struct ip ip;
  259.  
  260.   /* Service the loopback queue */
  261.   if((bp = dequeue(&loopq)) != NULLBUF)
  262.   {
  263.     dump(&loopback, IF_TRACE_IN, TRACE_IP, bp);  /* Extract IP header */
  264.     ntohip(&ip,&bp);
  265.     ip_recv(&ip,bp,0);
  266.   }
  267.   /* Service the interfaces */
  268.   for (ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  269.   {
  270.     if (ifp->recv != NULLVFP)
  271.     {
  272.       (*ifp->recv)(ifp);
  273.       if (ifp->driver != NULL)
  274.         (*ifp->driver)(DRIVER_POLL, ifp->subdevice);
  275.     }
  276.   }
  277.  
  278.   /* Service the clock if it has ticked */
  279.   check_time();
  280. }
  281.  
  282. /* Standard commands called from main */
  283.  
  284. /* Enter command mode */
  285. int cmdmode(void)
  286. {
  287.   if (mode != CMD_MODE)
  288.   {
  289.     mode = CMD_MODE;
  290.     cooked();
  291.     cwprintf(MWin, prompt);
  292.   }
  293.   return 0;
  294. }                  
  295.  
  296. static int doexit(int argc, char **argv)
  297. {
  298.   argc = argc;
  299.   argv = argv;
  300.  
  301.   net_exit();
  302.  
  303.   return(0);
  304. }
  305.  
  306. void net_exit(void)
  307. {
  308.   iostop();
  309.   exit(0);
  310. }
  311.  
  312. static int dohostname(int argc, char **argv)
  313. {
  314.   if(argc < 2)
  315.     cwprintf(NULL, "%s\r\n",hostname);
  316.   else 
  317.     strncpy(hostname,argv[1],HOSTNAMELEN);
  318.   return 0;
  319. }
  320.  
  321. static char logname[80];
  322.  
  323. static int dolog(int argc, char **argv)
  324. {
  325.   if(argc < 2)
  326.   {
  327.     if(logname[0])
  328.       cwprintf(NULL, "Logging to %s\r\n", logname);
  329.     else
  330.         cwprintf(NULL, "Logging off\r\n");
  331.     return 0;
  332.   }
  333.   if(strcmp(argv[1], "stop") != 0)
  334.   {
  335.     strcpy(logname, argv[1]);
  336.   }
  337.   else
  338.       {
  339.     logname[0] = '\0';
  340.   }
  341.   return 0;
  342. }
  343.  
  344. static int dohelp(int argc, char **argv)
  345. {
  346.   register struct cmds *cmdp;
  347.   register char *s;
  348.   int i, j;
  349.  
  350.   argc = argc;
  351.   argv = argv;
  352.  
  353.   if ((s = malloc(2000)) == NULL) return 0;
  354.  
  355.   sprintf(s, "Main commands:\r\n");
  356.  
  357.   for (i = 0, cmdp = cmds; cmdp->name != NULL; cmdp++, i++)
  358.   {
  359.     strcat(s, cmdp->name);
  360.  
  361.     if ((i % 4) == 3)
  362.     {
  363.       strcat(s, "\r\n");
  364.     } 
  365.     else {
  366.       for (j = strlen(cmdp->name); j < 16; j++)
  367.         strcat(s, " ");
  368.     }
  369.   }
  370.  
  371.   if ((i % 4) != 0) strcat(s, "\r\n");
  372.  
  373.   cwputs(NULL, s);
  374.  
  375.   free(s);
  376.  
  377.   return 0;
  378. }
  379.  
  380. static int doecho(int argc, char **argv)
  381. {
  382.   extern int refuse_echo;
  383.  
  384.   if(argc < 2)
  385.   {
  386.     if(refuse_echo)
  387.       cwprintf(NULL, "Refuse\r\n");
  388.     else
  389.       cwprintf(NULL, "Accept\r\n");
  390.   } 
  391.   else
  392.   {
  393.     if(argv[1][0] == 'r')
  394.       refuse_echo = 1;
  395.     else if(argv[1][0] == 'a')
  396.       refuse_echo = 0;
  397.     else
  398.       return -1;
  399.   }
  400.   return 0;
  401. }
  402.  
  403. static int doremote(int argc, char **argv)
  404. {
  405.   struct socket fsock, lsock;
  406.   struct mbuf *bp;
  407.  
  408.   argc = argc;
  409.  
  410.   lsock.address = ip_addr;
  411.   fsock.address = resolve(argv[1]);
  412.   lsock.port    = fsock.port = atoi(argv[2]);
  413.   bp = alloc_mbuf(1);
  414.   if (strcmp(argv[3], "reset") == 0)
  415.   {
  416.     *bp->data = SYS_RESET;
  417.   } 
  418.   else if (strcmp(argv[3], "exit") == 0)
  419.   {
  420.     *bp->data = SYS_EXIT;
  421.   } 
  422.   else if (strcmp(argv[3], "kick") == 0)
  423.   {
  424.     *bp->data = SYS_KICK;
  425.   } 
  426.   else
  427.   {
  428.     cwprintf(NULL, "Unknown command %s\r\n", argv[3]);
  429.     return(1);
  430.   }
  431.   bp->cnt = 1;
  432.   send_udp(&lsock, &fsock, 0, 0, bp, 0, 0, 0);
  433.   return(0);
  434. }
  435.  
  436. /* if unattended mode is set - restrict ax25 and telnet sessions */
  437. static int dounattend(int argc, char **argv)
  438. {
  439.   if(argc < 2)
  440.   {
  441.     if(attended)
  442.       cwprintf(NULL, "System in attended operation.\r\n");
  443.     else
  444.         cwprintf(NULL, "System in unattended operation.\r\n");
  445.   } 
  446.   else
  447.       {
  448.     if(argv[1][0] == 'y')
  449.     {
  450.       attended = 0;
  451.       cwprintf(NULL, "System now in unattended operation.\r\n");
  452.     }
  453.     else if(argv[1][0] == 'n')
  454.     {
  455.       attended = 1;
  456.       cwprintf(NULL, "System now in attended operation.\r\n");
  457.     }
  458.     else
  459.     {
  460.       cwprintf(NULL, "Usage : unattended y|n\r\n");
  461.       return -1;
  462.     }
  463.   }
  464.   return 0;
  465. }
  466.  
  467. /* set for unix end of line for remote echo mode telnet */
  468. static int doeol(int argc, char **argv)
  469. {
  470.   extern int unix_line_mode;
  471.  
  472.   if(argc < 2){
  473.     if(unix_line_mode)
  474.       cwprintf(NULL, "Unix\r\n");
  475.     else
  476.         cwprintf(NULL, "Standard\r\n");
  477.   } 
  478.   else {
  479.     if(strcmp(argv[1],"unix") == 0)
  480.       unix_line_mode = 1;
  481.     else if(strcmp(argv[1],"standard") == 0)
  482.       unix_line_mode = 0;
  483.     else {
  484.       return -1;
  485.     }
  486.   }
  487.   return 0;
  488. }
  489. /* Attach an interface
  490.  * Syntax: attach <hw type> <hw name> <mode> <label> <bufsize> [<speed>]
  491.  */
  492. static int doattach(int argc, char **argv)
  493. {
  494.   extern struct cmds attab[];
  495.  
  496.   return subcmd(attab,argc,argv);
  497. }
  498. /* Manipulate I/O device parameters */
  499. static int doparam(int argc, char **argv)
  500. {
  501.   register struct interface *ifp;
  502.  
  503.   for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next)
  504.   {
  505.     if(strcmp(argv[1],ifp->name) == 0)
  506.       break;
  507.   }
  508.   if(ifp == NULLIF)
  509.   {
  510.     cwprintf(NULL, "Interface \"%s\" unknown\r\n",argv[1]);
  511.     return 1;
  512.   }
  513.   if(ifp->ioctl == NULLFP)
  514.   {
  515.     cwprintf(NULL, "Not supported\r\n");
  516.     return 1;
  517.   }
  518.   /* Pass rest of args to device-specific code */
  519.   return (*ifp->ioctl)(ifp,argc-2,argv+2);
  520. }
  521.  
  522. /* Log messages of the form
  523.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  524.  */
  525. void log_event(struct tcb *tcb, char *fmt, ...)
  526. {
  527.   va_list argptr;
  528.   char *cp;
  529.   time_t t;
  530.   FILE *logfp;
  531.  
  532.   if (logname[0] == '\0')
  533.     return;
  534.   if (logfp = fopen(logname, "a+"), logfp == NULLFILE)
  535.     return;
  536.   time(&t);
  537.   cp = ctime(&t);
  538.   rip(cp);
  539.   fprintf(logfp, "%s %s - ", cp, psocket(&tcb->conn.remote));
  540.   va_start(argptr,fmt);   
  541.   vfprintf(logfp,fmt,argptr);
  542.   va_end(argptr);
  543.   fprintf(logfp,"\n");
  544.   fclose(logfp);
  545. }
  546. /* Configuration-dependent code */
  547.  
  548. /* List of supported hardware devices */
  549.  
  550. struct cmds attab[] = {
  551.  
  552.   /* Ordinary PC asynchronous adaptor */
  553.   "asy", asy_attach, 8, 
  554.   "attach asy <driver> <subdevice> slip|ax25|nrs <label> <buffers> <mtu> <speed>\r\n        <nrs call>",
  555.   "Could not attach asy",
  556.   "ppp", ppp_attach,     1, "attach ppp", "Could not attach ppp",
  557.  
  558.   /* fake netrom interface */
  559.   "netrom", nr_attach, 1,
  560.   "attach netrom",
  561.   "Could not attach netrom",
  562.  
  563.   NULLCHAR, NULLFP, 0,
  564.   "Unknown device",
  565.   NULLCHAR,
  566. };
  567.  
  568. /* Protocol tracing function pointers */
  569. void (*tracef[])() = {
  570.   ax25_dump,
  571.  
  572.   NULLVFP,
  573.   ip_dump,
  574.  
  575.  
  576.   NULLVFP,
  577. };
  578.  
  579.  
  580. /* Attach a serial interface to the system
  581.  * argv[0]: hardware type, must be "asy"
  582.  * argv[1]: async adapter type, e.g. internal
  583.  * argv[2]: async adapter port number
  584.  * argv[3]: mode, may be:
  585.  *          "slip" (point-to-point SLIP)
  586.  *          "ax25" (AX.25 frame format in SLIP for raw TNC)
  587.  *          "nrs" (NET/ROM format serial protocol)
  588.  * argv[4]: interface label, e.g., "sl0"
  589.  * argv[5]: receiver ring buffer size in bytes
  590.  * argv[6]: maximum transmission unit, bytes
  591.  * argv[7]: interface speed, e.g, "9600"
  592.  * argv[8]: optional ax.25 callsign (NRS only)
  593.  */
  594. static int asy_attach(int argc, char **argv)
  595. {
  596.   register struct interface *if_asy;
  597.   extern struct interface *ifaces;
  598.   int dev;
  599.   int mode;
  600.   struct ax25_addr addr ;
  601.  
  602.   if(nasy >= ASY_MAX){
  603.     cwprintf(NULL, "Too many asynch controllers\r\n");
  604.     return -1;
  605.   }
  606.  
  607.   /* Create interface structure and fill in details */
  608.   if_asy = (struct interface *)calloc(1,sizeof(struct interface));
  609.   if_asy->name = malloc((unsigned)strlen(argv[4])+1);
  610.  
  611.   strcpy(if_asy->name,argv[4]);
  612.   if_asy->mtu  = atoi(argv[6]);
  613.   if_asy->dev  = dev;
  614.   if_asy->recv = doslip;
  615.   if_asy->stop = asy_stop;
  616.  
  617.   /* Get driver */
  618.   if ((if_asy->driver=driver_load(argv[1]))==NULL)
  619.   {
  620.     cwprintf(NULL, "can't load asy driver \"%s\"\r\n",argv[1]);
  621.     return -1;
  622.   }
  623.   if_asy->subdevice = atoi(argv[2]);
  624.  
  625.   if(strcmp(argv[3],"slip") == 0)
  626.     mode = SLIP_MODE;
  627.   else if(strcmp(argv[3],"ax25") == 0)
  628.     mode = AX25_MODE;
  629.   else if(strcmp(argv[3],"nrs") == 0)
  630.     mode = NRS_MODE;
  631.   else 
  632.       mode = UNKNOWN;
  633.  
  634.   dev = nasy++;
  635.  
  636.  
  637.   switch(mode)
  638.   {
  639.   case SLIP_MODE:
  640.     if_asy->ioctl = asy_ioctl;
  641.     if_asy->send = (int(*)())slip_send;
  642.     if_asy->output = NULLFP;        /* ARP isn't used */
  643.     if_asy->raw = slip_raw;
  644.     if_asy->flags = 0;
  645.     slip[dev].recv = slip_recv;
  646.     break;
  647.   case AX25_MODE:  /* Set up a SLIP link to use AX.25 */
  648.     axarp();
  649.     if(argc < 9)
  650.     {
  651.       /* no call sign supplied */
  652.       if(mycall.call[0] == '\0')
  653.       {
  654.         cwprintf(NULL, "set mycall first or specify in attach statement\r\n");
  655.         free(if_asy->name);
  656.         free((char *)if_asy);
  657.         nasy--;
  658.         return -1;
  659.       }
  660.       else
  661.           {
  662.         addr = mycall;
  663.       }
  664.     }
  665.     else
  666.     {
  667.       /* callsign supplied on attach line */
  668.       if(setcall(&addr,argv[8]) == -1)
  669.       {
  670.         cwprintf (NULL, "bad callsign on attach line\r\n");
  671.         free(if_asy->name);
  672.         free((char *)if_asy);
  673.         nasy--;
  674.         return -1;
  675.       }
  676.     }
  677.     if_asy->ioctl = kiss_ioctl;
  678.     if_asy->send = (int(*)())ax_send;
  679.     if_asy->output = (int(*)())ax_output;
  680.     if_asy->raw = kiss_raw;
  681.     if(if_asy->hwaddr == NULLCHAR)
  682.       if_asy->hwaddr = malloc(sizeof(addr));
  683.     memcpy(if_asy->hwaddr,(char *)&addr,sizeof(addr));
  684.     slip[dev].recv = kiss_recv;
  685.     break;
  686.   case NRS_MODE: /* Set up a net/rom serial interface */
  687.     if(argc < 9)
  688.     {
  689.       /* no call supplied? */
  690.       if(mycall.call[0] == '\0')
  691.       {
  692.         /* try to use default */
  693.         cwprintf(NULL, "set mycall first or specify in attach statement\r\n");
  694.         return -1;
  695.       } 
  696.       else
  697.           addr = mycall;
  698.     } 
  699.     else
  700.     {
  701.       /* callsign supplied on attach line */
  702.       if(setcall(&addr,argv[8]) == -1){
  703.         cwprintf (NULL, "bad callsign on attach line\r\n");
  704.         free(if_asy->name);
  705.         free((char *)if_asy);
  706.         nasy--;
  707.         return -1;
  708.       }
  709.     }
  710.     if_asy->recv = nrs_recv;
  711.     if_asy->ioctl = asy_ioctl;
  712.     if_asy->send = (int(*)())ax_send;
  713.     if_asy->output = (int(*)())ax_output;
  714.     if_asy->raw = nrs_raw;
  715.     if(if_asy->hwaddr == NULLCHAR)
  716.       if_asy->hwaddr = malloc(sizeof(addr));
  717.     memcpy(if_asy->hwaddr,(char *)&addr,sizeof(addr));
  718.     nrs[dev].iface = if_asy;
  719.     break;
  720.   default:
  721.     cwprintf(NULL, "Mode %s unknown for interface %s\r\n",
  722.     argv[2],argv[4]);
  723.     free(if_asy->name);
  724.     free((char *)if_asy);
  725.     nasy--;
  726.     return -1;
  727.   }
  728.   if_asy->next = ifaces;
  729.   ifaces = if_asy;
  730.   asy_init(dev, if_asy, (unsigned)atoi(argv[5]));
  731.   if (atoi(argv[7]))
  732.     asy_speed(dev, atoi(argv[7]));
  733.   return 0;
  734. }
  735.  
  736.  
  737. /* Display or set IP interface control flags */
  738. static int domode(int argc, char **argv)
  739. {
  740.   register struct interface *ifp;
  741.  
  742.   for(ifp=ifaces;ifp != NULLIF;ifp = ifp->next){
  743.     if(strcmp(argv[1],ifp->name) == 0)
  744.       break;
  745.   }
  746.   if(ifp == NULLIF){
  747.     cwprintf(NULL, "Interface \"%s\" unknown\r\n",argv[1]);
  748.     return 1;
  749.   }
  750.   if(argc < 3){
  751.     cwprintf(NULL, "%s: %s\r\n",ifp->name,
  752.     (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  753.     return 0;
  754.   }
  755.   switch(argv[2][0]){
  756.   case 'v':
  757.   case 'c':
  758.   case 'V':
  759.   case 'C':
  760.     ifp->flags = CONNECT_MODE;
  761.     break;
  762.   case 'd':
  763.   case 'D':
  764.     ifp->flags = DATAGRAM_MODE;
  765.     break;
  766.   default:
  767.     cwprintf(NULL, "Usage: %s [vc | datagram]\r\n",argv[0]);
  768.     return 1;
  769.   }
  770.   return 0;
  771. }
  772.  
  773. static int dostart(int argc, char **argv)
  774. {
  775.   return subcmd(startcmds,argc,argv);
  776. }
  777. static int dostop(int argc, char **argv)
  778. {
  779.   return subcmd(stopcmds,argc,argv);
  780. }
  781.  
  782. static int dotrace(int argc, char **argv)
  783. {
  784.   struct interface *ifp;
  785.   struct interface *ifpp;
  786.   int tracing = 0;
  787.  
  788.   if(argc < 2){
  789.     showtrace(&loopback);
  790.     for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  791.       showtrace(ifp);
  792.     return 0;
  793.   }
  794.   if(strcmp("loopback",argv[1]) == 0)
  795.     ifp = &loopback;
  796.   else 
  797.       for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  798.     if(strcmp(ifp->name,argv[1]) == 0)
  799.       break;
  800.  
  801.   if(ifp == NULLIF){
  802.     cwprintf(NULL, "Interface %s unknown\r\n",argv[1]);
  803.     return 1;
  804.   }
  805.   if(argc >= 3){
  806.     if ((ifp->trace = htoi(argv[2])) > 0)
  807.     {
  808.       twopen();
  809.     } 
  810.     else {
  811.       for(ifpp = ifaces; ifpp != NULLIF; ifpp = ifpp->next)
  812.         if (ifpp->trace > 0)
  813.           tracing = 1;
  814.       if (loopback.trace > 0)
  815.         tracing = 1;
  816.       if (!tracing)
  817.         twclose();
  818.     }
  819.   } 
  820.   showtrace(ifp);
  821.   return 0;
  822. }
  823. /* Display the trace flags for a particular interface */
  824. static void showtrace(register struct interface *ifp)
  825. {
  826.   if(ifp == NULLIF)
  827.     return;
  828.   cwprintf(NULL, "%s:",ifp->name);
  829.   if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT)){
  830.     if(ifp->trace & IF_TRACE_IN)
  831.       cwprintf(NULL, " input");
  832.     if(ifp->trace & IF_TRACE_OUT)
  833.       cwprintf(NULL, " output");
  834.  
  835.     if(ifp->trace & IF_TRACE_HEX)
  836.       cwprintf(NULL, " (Hex/ASCII dump)");
  837.     else if(ifp->trace & IF_TRACE_ASCII)
  838.       cwprintf(NULL, " (ASCII dump)");
  839.     else
  840.         cwprintf(NULL, " (headers only)");
  841.     cwprintf(NULL, "\r\n");
  842.   } 
  843.   else
  844.       cwprintf(NULL, " tracing off\r\n");
  845. }
  846.  
  847. void stoptrace(void)
  848. {
  849.   struct interface *ifp;
  850.  
  851.   loopback.trace = 0;
  852.   for(ifp = ifaces; ifp != NULLIF; ifp = ifp->next)
  853.     ifp->trace = 0; 
  854. }
  855.  
  856. static int dosource(int argc, char **argv)
  857. {
  858.   static char inbuf[200], savebuf[200]; /* keep it off the stack */
  859.   char filename[80];                    /* for error messages */
  860.   int linenum = 0;
  861.   FILE *fp;
  862.  
  863.   argc = argc; 
  864.  
  865.   if ((fp = fopen(argv[1], "r")) == NULLFILE)
  866.   {
  867.     cwprintf(NULL, "%s: cannot open\r\n", argv[1]);
  868.     return 1;
  869.   }
  870.  
  871.   strcpy(filename, argv[1]);
  872.  
  873.   while (fgets(inbuf, sizeof(inbuf),fp) != NULLCHAR)
  874.   {
  875.     rip(inbuf);
  876.     strcpy(savebuf, inbuf);
  877.     cwprintf(NULL, "%s\r\n", inbuf);
  878.     linenum++;
  879.     if (cmdparse(cmds, inbuf, NULL) != 0)
  880.       cwprintf(NULL, "*** file \"%s\", line %d: %s\r\n", filename, linenum, savebuf);
  881.   }
  882.   fclose(fp);
  883.   return 0;
  884. }
  885.